//
// Created by miaomiaole on 2024/6/22.
//
#pragma once

#include <string>
#include <memory>

class SpreadSheetCell {
public:

    SpreadSheetCell() = default;

    SpreadSheetCell(double initvalue);

    ~SpreadSheetCell();


    SpreadSheetCell(double initvalue, std::string variable_name);

    // 拷贝构造
    SpreadSheetCell(SpreadSheetCell *src);

    // 拷贝构造
    SpreadSheetCell(SpreadSheetCell const &&src);


    SpreadSheetCell &operator=(SpreadSheetCell &rhs);

    void display();

    double getInitValue() const;

    void setInitValue(double initValue);

    const std::string &getVariableName() const;

    void setVariableName(const std::string &variableName);


private:
    double initValue;
    std::string variable_name;
};


class SpreadSheet {
public:
    SpreadSheet(size_t width, size_t height);

    void setCellAt(size_t x, size_t y, const SpreadSheetCell &cell);

    SpreadSheetCell &getCellAt(size_t x, size_t y);

private:
    bool inRange(size_t value, size_t upper) const;

    size_t m_width{0};
    size_t m_height{0};
    SpreadSheetCell **m_cells{nullptr};
};

class Car;

class Driver {
public:
    void drive(Car &car);
};

class Car {
private:
    double fuel;
public:
    Car(double f) : fuel(f) {}

    // 友元方法，在Car中定义Driver的drive
    friend void Driver::drive(Car &car);
};


class Base {
public:
    Base();

    Base(std::string_view str) : str(str) {};

    Base(float f) : f(f) {};

    virtual void go() {
        std::cout << "go() called on Base " << std::endl;
    }

    virtual ~Base();

private:
    std::string_view str;
    float f;
};

class Derived : public Base {
private:
    char *m_string;
public:
    void go() {
        std::cout << "go() called on Derived " << std::endl;
    };

    Derived() {
        m_string = new char[30];
        std::cout << " generate Derived" << std::endl;
    }

    ~Derived() override;
};


class something {
public:
    something();

    virtual ~something();
};

class base {
public:
    base();

    virtual ~base();
};

class derived : public base {
public:
    derived();

    virtual ~derived();

private:
    something m_something;
};


class book {
public:
    virtual ~book() = default;

    virtual std::string getDescription() const { return "book"; }

    virtual int getHeight() const { return 100; }

};

class paper_back : public book {
public:
    std::string getDescription() const {
        return "parer_back" + book::getDescription();
    }
};

class romance : public paper_back {
public:
    std::string getDescription() const {
        return "parer_back" + paper_back::getDescription();
    }

    int getHeight() const {
        return 20 + book::getHeight();
    }
};

class technical : public romance {
public:
    std::string getDescription() const {
        return "parer_back" + book::getDescription();
    }

    int getHeight() const {
        return 20 + paper_back::getHeight();
    }
};

class logger {
public:
    logger() {
        std::cout << "Logger constructed" << std::endl;
    }

    ~logger() {
        std::cout << "Logger destroyed" << std::endl;
    }

    void log(const std::string &message) {
        std::cout << "Logging: " << message << std::endl;
    }
};

class my_class {
private:
    logger logger;
public:
    my_class() {
        std::cout << "MyClass constructed" << std::endl;
    }

    ~my_class() {
        std::cout << "MyClass destroyed" << std::endl;
    }

    void performTask() {
        logger.log("Performing task");
    }
};

class bird {
public:
    virtual void chirp() {
        std::cout << "chirp" << std::endl;
    }

    virtual void eat() {
        std::cout << "the bird ate " << std::endl;
    }
};


class dog {
public:
    virtual void bark() {
        std::cout << "woof" << std::endl;
    }

    virtual void eat() {
        std::cout << "eat " << std::endl;
    }
};


class bog_bird : public bird, public dog {

};


template<typename T>
class Grid {
public:
    explicit Grid(size_t width, size_t height);

    virtual ~Grid();

    Grid(const Grid &src) = default;
};


class Point {
public:
    // 自身++
    Point &operator++();

    Point operator++(int);

    Point &operator--();

    Point operator--(int);

private:
    int _x, _y;
};

// 内部类
class my_class_impl {
private:
    class impl;

    std::unique_ptr<impl> pid_t;
};


class Box {
public:
    // default constructor
    Box() {};

    // 不能用于隐式转换和复制初始化
    explicit Box(int i) : m_width(i), m_length(i), m_height(i) {}

    Box(int width, int length, int height)
            : m_width(width), m_length(length), m_height(height) {}


    // all  copy constructor
    Box(Box &other) = default;

    Box(const Box &other) = default;


    // move constructor
    Box(Box &&other) = default;

    int Volume() { return m_width * m_length * m_height; }

private:
    int m_width{0};
    int m_length{0};
    int m_height{0};
};


class Contained1 {
public:
    Contained1() { std::cout << "Contained1 ctor\n"; }
};

class Contained2 {
public:
    Contained2() { std::cout << "Contained2 ctor\n"; }
};

class Contained3 {
public:
    Contained3() { std::cout << "Contained3 ctor\n"; }
};


class BaseContainer {
public:
    BaseContainer() { std::cout << "BaseContainer ctor\n"; }

private:
    Contained1 c1;
    Contained2 c2;
};

// 父类成员初始化
// 父类构造
// 子类成员初始化
// 子类构造
class DerivedContainer : public BaseContainer {
public:
    DerivedContainer() : BaseContainer() { std::cout << "DerivedContainer ctor\n"; };

private:
    Contained3 c3;
};


class my_class_2 {
public:
    int num;
    std::string name;

    void print() {
        std::cout << name << " : " << num << std::endl;
    }
};

void lambda_func();


// 重写new运算符
class Blanks {
public:
    Blanks() {}

    void *operator new(size_t stAllocateBlock, char chInit);

    void operator delete(void *);

    void operator delete(void *, size_t);
};

//带参数的模板
template<typename T, size_t size>
T minimum(const T &lhs, const T &rhs) {
    auto arr = new int[size];
    return lhs < rhs ? lhs : rhs;
}

template<typename ...A>
void print(A ...args) {
    (std::cout << ... << args) << std::endl;
}

// 任意参数模板
template<typename ...A>
class my_class_3 {
public:
    my_class_3(A... args) : data(args...) {}

private:
    std::tuple<A...> data;
};

template<typename U, int I>
class Array {
public:
    U data[I];

    U &operator[](int index) {
        return data[index];
    }

    const U &operator[](int index) const {
        return data[index];
    }

    int size() const {
        return I;
    }
};

// 模板嵌套，定义Arr类的模板 U,I
template<typename T, template<typename U, int I> class Arr>
class Container {
public:
    //  使用 Arr 模板类创建一个大小为 10 的数组
    Arr<T, 10> arr;

    void fill(const T &value) {
        for (int i = 0; i < arr.size(); ++i) {
            arr[i] = value;
        }
    }

    void print() const {
        for (int i = 0; i < arr.size(); ++i) {
            std::cout << arr[i] << " ";
        }
        std::cout << std::endl;
    }
};

template<class T, int i = 10>
class my_stack {
private:
    std::unique_ptr<T> ptr;
    T StackBuffer[i];
};
